﻿Imports System.Web
Imports System.Configuration
Imports System.Text

''' <summary>
''' NetBouncer
''' Input sanitization / filter and control class, spesifically designed to protect web applications.
''' </summary>
''' <remarks></remarks>
Public Class NetBouncer
    Inherits ConfigurationSection

#Region "Config Sections"

    ''' <summary>
    ''' Gets the RuleSets.
    ''' </summary>
    ''' <value>The RuleSets.</value>
    <ConfigurationProperty("rulesets", IsDefaultCollection:=False)> _
    Public ReadOnly Property RuleSets() As RuleSetCollection
        Get
            Return CType(Me("rulesets"), RuleSetCollection)
        End Get
    End Property


    ''' <summary>
    ''' Gets the Custom Rules Definition Collection.
    ''' </summary>
    ''' <value>Custom Rules Collection.</value>
    <ConfigurationProperty("customrules", IsDefaultCollection:=False)> _
    Public ReadOnly Property CustomRuleDefinitions() As CustomRuleDefinitionCollection
        Get
            Return CType(MyBase.Item("customrules"), CustomRuleDefinitionCollection)
        End Get
    End Property


    ''' <summary>
    ''' Gets the RuleSet .
    ''' </summary>
    ''' <param name="value">The value.</param>
    ''' <returns>Selected RuleSet</returns>
    Public Shared Function GetRuleSet(ByVal value As String) As RuleSet(Of String)
        Return NetBouncer.GetInstance().RuleSets(value)
    End Function

#End Region


    ''' <summary>
    ''' Initializes a new instance of the <see cref="NetBouncer" /> class.
    ''' </summary>
    Private Sub New()
    End Sub

#Region "Singleton"

    Private Shared Instance As NetBouncer

    ''' <summary>
    ''' Get the instance of Netbouncer
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GetInstance() As NetBouncer
        If Instance Is Nothing Then Instance = CType(ConfigurationManager.GetSection("NetBouncer"), NetBouncer)
        Return Instance
    End Function


#End Region

    ''' <summary>
    ''' Get Secure Querystring Parameter ( Don't forget to use .IsValid() )
    ''' </summary>
    ''' <param name="key"></param>
    ''' <param name="ruleSet"></param>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared ReadOnly Property QueryStringAsInteger(ByVal key As String, ByVal ruleSet As RuleSet(Of String)) As IntegerParameter
        Get
            Return New IntegerParameter(HttpContext.Current.Request.QueryString(key), ruleSet)
        End Get
    End Property

    ''' <summary>
    ''' Gets the querystring as integerParameter from ruleSetName.
    ''' </summary>
    ''' <value>The querystring as integer.</value>
    Public Shared ReadOnly Property QueryStringAsInteger(ByVal key As String, ByVal ruleSetName As String) As IntegerParameter
        Get
            Return QueryStringAsInteger(key, NetBouncer.GetRuleSet(ruleSetName))
        End Get
    End Property

    ''' <summary>
    ''' Gets the querystring as integerParameter. RuleSet Name should be same with the parameter name.
    ''' </summary>
    ''' <value>The querystring as integer.</value>
    Public Shared ReadOnly Property QueryStringAsInteger(ByVal key As String) As IntegerParameter
        Get
            Return QueryStringAsInteger(key, key)
        End Get
    End Property


    '''' <summary>
    '''' Get Secure Querystring Parameter ( Don't forget to use .IsValid() )
    '''' </summary>
    '''' <param name="key"></param>
    '''' <param name="ruleSet"></param>
    '''' <value></value>
    '''' <returns></returns>
    '''' <remarks></remarks>
    'Public Shared ReadOnly Property QueryStringAsInteger(ByVal key As String, ByVal ruleSet As RuleSet(Of String)) As Parameter
    '    Get
    '        Return New BaseParameter(Of String, Integer)(HttpContext.Current.Request.QueryString(key), ruleSet)
    '    End Get
    'End Property


    ''' <summary>
    ''' Gets the Hostname (HTTP_HOST).
    ''' </summary>
    ''' <value>The hostname.</value>
    Public Shared ReadOnly Property Hostname() As Parameter
        Get
            Return ServerVariables("HTTP_HOST", FM.NetBouncer.RuleSets.HostNameSet)
        End Get
    End Property

    ''' <summary>
    ''' Servers the variables.
    ''' </summary>
    ''' <param name="key">The key.</param>
    ''' <param name="ruleSet">The rule set.</param>
    ''' <returns></returns>
    Public Shared Function ServerVariables(ByVal key As String, ByVal ruleSet As RuleSet(Of String)) As Parameter
        Return New Parameter(HttpContext.Current.Request.ServerVariables(key), ruleSet)
    End Function

    ''' <summary>
    ''' Get Secure Querystring Parameter ( Don't forget to use .IsValid() )
    ''' </summary>
    ''' <value>The query string as string.</value>
    ''' <param name="key"></param>
    ''' <param name="ruleSet"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared ReadOnly Property QueryStringAsString(ByVal key As String, ByVal ruleSet As RuleSet(Of String)) As Parameter
        Get
            Return New Parameter(HttpContext.Current.Request.QueryString(key), ruleSet)
        End Get
    End Property


    Public Shared ReadOnly Property QueryStringAsString(ByVal key As String, ByVal ruleSetName As String) As Parameter
        Get
            Return QueryStringAsString(key, GetRuleSet(ruleSetName))
        End Get
    End Property

    Public Shared ReadOnly Property QueryStringAsString(ByVal key As String) As Parameter
        Get
            Return QueryStringAsString(key, key)
        End Get
    End Property


    ''' <summary>
    ''' Gets Request.Form as string.
    ''' </summary>
    ''' <value>The Request.Form as string.</value>
    Public Shared ReadOnly Property FormAsString(ByVal key As String, ByVal ruleSet As RuleSet(Of String)) As Parameter
        Get
            Return New Parameter(HttpContext.Current.Request.Form(key), ruleSet)
        End Get
    End Property

    Public Shared ReadOnly Property FormAsString(ByVal key As String, ByVal ruleSetName As String) As Parameter
        Get
            Return FormAsString(key, GetRuleSet(ruleSetName))
        End Get
    End Property

    Public Shared ReadOnly Property FormAsString(ByVal key As String) As Parameter
        Get
            Return FormAsString(key, key)
        End Get
    End Property

    ''' <summary>
    '''  Gets the form as integerParameter from ruleSet.
    ''' </summary>
    ''' <value>The Request.Form as integer.</value>
    Public Shared ReadOnly Property FormAsInteger(ByVal key As String, ByVal ruleSet As RuleSet(Of String)) As IntegerParameter
        Get
            Return New IntegerParameter(HttpContext.Current.Request.Form(key), ruleSet)
        End Get
    End Property

    ''' <summary>
    ''' Gets the form as integerParameter from ruleSetName.
    ''' </summary>
    ''' <value>The form as integer.</value>
    Public Shared ReadOnly Property FormAsInteger(ByVal key As String, ByVal ruleSetName As String) As IntegerParameter
        Get
            Return FormAsInteger(key, NetBouncer.GetRuleSet(ruleSetName))
        End Get
    End Property

    ''' <summary>
    ''' Gets the form as integerParameter. RuleSet Name should be same with the parameter name.
    ''' </summary>
    ''' <value>The form as integer.</value>
    Public Shared ReadOnly Property FormAsInteger(ByVal key As String) As IntegerParameter
        Get
            Return FormAsInteger(key, key)
        End Get
    End Property



    ''' <summary>
    ''' Returns a <see cref="T:System.String" /> that represents the current <see cref="T:System.Object" />.
    ''' </summary>
    ''' <returns>
    ''' A <see cref="T:System.String" /> that represents the current <see cref="T:System.Object" />.
    ''' </returns>
    Public Overrides Function ToString() As String

        Dim Explain As New StringBuilder(1000)
        With Explain

            .AppendLine("== Custom Rule Definitions ==")
            '.AppendLine("DLL to Load : " & Me.CustomRuleDefinitions.Type)

            For Each CustomRuleDef As CustomRuleDefinition In Me.CustomRuleDefinitions
                .AppendLine("Custom Rule Class " & CustomRuleDef.Type)
            Next

            .AppendLine("== RuleSets ==")
            For Each RuleSet As RuleSet(Of String) In Me.RuleSets

                .AppendLine(vbTab & "= " & RuleSet.Name & "=")
                For Each Rule As IRule(Of String) In RuleSet.Rules
                    .AppendLine(vbTab & vbTab & Rule.ToString)
                Next

                .AppendLine(vbTab & "= Custom Rules =")
                For Each CustomRule As CustomRule In RuleSet.CustomRuleCollection
                    .AppendLine(vbTab & vbTab & "-- " & CustomRule.Name)
                Next

            Next


        End With

        Return Explain.ToString()
    End Function


End Class
